<template>
  <div class="json-tool">
    <el-card class="tool-card">
      <template #header>
        <div class="card-header">
          <span>JSON工具</span>
          <div class="header-actions">
            <el-switch
              v-model="autoFormat"
              active-text="实时格式化"
              inactive-text="手动格式化"
              style="--el-switch-on-color: #13ce66;"
            />
            <el-button type="primary" @click="formatJson" :disabled="!inputText || autoFormat">
              <el-icon><MagicStick /></el-icon>
              格式化
            </el-button>
            <el-button @click="compressJson" :disabled="!inputText">
              <el-icon><FolderDelete /></el-icon>
              压缩
            </el-button>
            <el-button @click="clearAll">
              <el-icon><Delete /></el-icon>
              清空
            </el-button>
          </div>
        </div>
      </template>

      <div class="json-container">
        <!-- 输入区域 -->
        <div class="input-section">
          <div class="section-header">
            <h4>输入JSON</h4>
            <el-button size="small" text @click="pasteFromClipboard">
              <el-icon><DocumentCopy /></el-icon>
              粘贴
            </el-button>
          </div>
          <el-input
            v-model="inputText"
            type="textarea"
            placeholder="请输入或粘贴JSON数据..."
            class="json-input"
            @input="validateJson"
          />
        </div>

        <!-- 输出区域 -->
        <div class="output-section">
          <div class="section-header">
            <h4>格式化结果</h4>
            <el-button size="small" text @click="copyToClipboard" :disabled="!outputText">
              <el-icon><CopyDocument /></el-icon>
              复制
            </el-button>
          </div>
          <el-input
            v-model="outputText"
            type="textarea"
            readonly
            placeholder="格式化结果将显示在这里..."
            class="json-output"
          />
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import {
  MagicStick,
  Delete,
  DocumentCopy,
  CopyDocument,
  FolderDelete
} from '@element-plus/icons-vue'

// LocalStorage 键名
const STORAGE_KEY = 'json-tool-input'
const AUTO_FORMAT_KEY = 'json-tool-auto-format'

const inputText = ref('')
const outputText = ref('')
const inputError = ref('')
const outputInfo = ref('')
const autoFormat = ref(true) // 自动格式化开关

// 验证JSON格式
const validateJson = () => {
  if (!inputText.value.trim()) {
    inputError.value = ''
    return false
  }

  try {
    JSON.parse(inputText.value)
    inputError.value = ''
    return true
  } catch (error) {
    inputError.value = `JSON格式错误: ${(error as Error).message}`
    return false
  }
}

// 格式化JSON
const formatJson = () => {
  if (!validateJson()) {
    ElMessage.error('请输入有效的JSON数据')
    return
  }

  try {
    const parsed = JSON.parse(inputText.value)
    outputText.value = JSON.stringify(parsed, null, 2)
    outputInfo.value = `格式化完成，原始大小: ${inputText.value.length} 字符，格式化后: ${outputText.value.length} 字符`
    ElMessage.success('JSON格式化成功')
  } catch (error) {
    ElMessage.error('格式化失败: ' + (error as Error).message)
  }
}

// 压缩JSON
const compressJson = () => {
  if (!validateJson()) {
    ElMessage.error('请输入有效的JSON数据')
    return
  }

  try {
    const parsed = JSON.parse(inputText.value)
    outputText.value = JSON.stringify(parsed)
    outputInfo.value = `压缩完成，原始大小: ${inputText.value.length} 字符，压缩后: ${outputText.value.length} 字符，节省: ${((1 - outputText.value.length / inputText.value.length) * 100).toFixed(1)}%`
    ElMessage.success('JSON压缩成功')
  } catch (error) {
    ElMessage.error('压缩失败: ' + (error as Error).message)
  }
}

// 清空所有内容
const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
  inputError.value = ''
  outputInfo.value = ''

  // 同时清除 localStorage 中保存的内容
  try {
    localStorage.removeItem(STORAGE_KEY)
  } catch (error) {
    console.error('清除 localStorage 失败:', error)
  }

  ElMessage.info('已清空所有内容')
}

// 从剪贴板粘贴
const pasteFromClipboard = async () => {
  try {
    const text = await navigator.clipboard.readText()
    inputText.value = text
    validateJson()
    ElMessage.success('已从剪贴板粘贴内容')
  } catch (error) {
    ElMessage.error('无法从剪贴板读取内容')
  }
}

// 复制到剪贴板
const copyToClipboard = async () => {
  if (!outputText.value) {
    ElMessage.warning('没有可复制的内容')
    return
  }

  try {
    await navigator.clipboard.writeText(outputText.value)
    ElMessage.success('已复制到剪贴板')
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

// 实时格式化JSON
const autoFormatJson = () => {
  if (!inputText.value.trim()) {
    outputText.value = ''
    outputInfo.value = ''
    inputError.value = ''
    return
  }

  try {
    const parsed = JSON.parse(inputText.value)
    outputText.value = JSON.stringify(parsed, null, 2)
    outputInfo.value = `已自动格式化，原始: ${inputText.value.length} 字符，格式化后: ${outputText.value.length} 字符`
    inputError.value = ''
  } catch (error) {
    // 只更新错误信息，不清空输出
    inputError.value = `JSON格式错误: ${(error as Error).message}`
    // 如果之前有正确的输出，保留它
  }
}

// 保存输入到 localStorage
const saveToLocalStorage = () => {
  try {
    localStorage.setItem(STORAGE_KEY, inputText.value)
  } catch (error) {
    console.error('保存到 localStorage 失败:', error)
  }
}

// 从 localStorage 加载输入
const loadFromLocalStorage = () => {
  try {
    const saved = localStorage.getItem(STORAGE_KEY)
    if (saved) {
      inputText.value = saved
    }

    // 加载自动格式化开关状态
    const savedAutoFormat = localStorage.getItem(AUTO_FORMAT_KEY)
    if (savedAutoFormat !== null) {
      autoFormat.value = savedAutoFormat === 'true'
    }
  } catch (error) {
    console.error('从 localStorage 加载失败:', error)
  }
}

// 监听输入变化，实时格式化并保存
watch(inputText, () => {
  if (autoFormat.value) {
    autoFormatJson()
  } else {
    validateJson()
  }
  // 保存到 localStorage
  saveToLocalStorage()
}, { immediate: false })

// 监听自动格式化开关变化，保存到 localStorage
watch(autoFormat, (newValue) => {
  try {
    localStorage.setItem(AUTO_FORMAT_KEY, String(newValue))
  } catch (error) {
    console.error('保存自动格式化设置失败:', error)
  }

  // 开关切换时，如果开启了自动格式化且有输入内容，立即格式化
  if (newValue && inputText.value.trim()) {
    autoFormatJson()
  }
})

// 组件挂载时加载保存的数据
onMounted(() => {
  loadFromLocalStorage()
})
</script>

<style scoped>
.json-tool {
  width: 100%;
  height: 100vh;
  background: transparent;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.tool-card {
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-light);
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.tool-card :deep(.el-card__header) {
  flex-shrink: 0;
}

.tool-card :deep(.el-card__body) {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0.5rem;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.json-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  flex: 1;
  overflow: hidden;
}

.input-section,
.output-section {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
  flex-shrink: 0;
}

.section-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--el-text-color-primary);
}

.json-input,
.json-output {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  line-height: 1.4;
  flex: 1;
  height: 100%;
}

.json-input :deep(.el-textarea),
.json-output :deep(.el-textarea) {
  height: 100%;
}

.json-input :deep(.el-textarea__inner),
.json-output :deep(.el-textarea__inner) {
  font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
  font-size: 13px;
  line-height: 1.4;
  height: 100%;
  resize: none;
}

.json-output :deep(.el-textarea__inner) {
  background-color: var(--el-fill-color-light);
}

/* 响应式适配 */
@media (max-width: 1200px) {
  .json-container {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 768px) {
  .card-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }

  .header-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  .header-actions .el-button {
    flex: 1;
    min-width: 100px;
  }

  .json-input :deep(.el-textarea__inner),
  .json-output :deep(.el-textarea__inner) {
    font-size: 12px;
  }

  .tool-card :deep(.el-card__body) {
    padding: 12px;
  }
}

/* 深色模式适配 */
.dark .tool-card {
  background: var(--el-bg-color);
  border-color: var(--el-border-color);
}

.dark .json-output :deep(.el-textarea__inner) {
  background-color: var(--el-fill-color-darker);
}
</style>